package calculateZhaGan;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class ZhaGanDemo {

	public static void main(String[] args) throws FileNotFoundException {
		PrintStream out = new PrintStream(new File("D:\\temp\\测试数据_20151229.txt"));
		System.setOut(out);
		
		// 轧钢原材料长度(mm)
		int target = 1526;
		
		// 测试案例一
		List<Integer> orders = new ArrayList<Integer>();// 需要生产的订单列表（长度）
		orders.add(80);
		orders.add(70);
		orders.add(65);
		orders.add(50);
		orders.add(47);
		orders.add(41);
		orders.add(35);
		orders.add(29);
		orders.add(21);
		orders.add(15);
		orders.add(11);
		orders.add(7);
		orders.add(4);
		
		ZhaGanDemo demo = new ZhaGanDemo();
//		demo.getPruductionPlan(orders, target);
		
		// 测试案例二
		orders.add(65);
		orders.add(65);
		orders.add(65);
		orders.add(65);
		orders.add(65);
		orders.add(20);
//		demo.getPruductionPlan(orders, target);
		
		// 真实订单_20151229
		Integer[] l1 = new Integer[]{400, 435, 480, 520, 560, 600, 570, 580, 450, 365, 385, 560, 505, 485, 440, 480, 438, 430, 305, 480, 353, 438, 430, 340, 348};
		Integer[] l2 = new Integer[]{348, 290, 272, 272, 258, 258, 273, 366, 386, 820, 870, 830, 750, 410, 365, 460, 456, 558, 360, 780, 895, 385, 300};
		Integer[] l3 = new Integer[]{826, 876, 876, 762, 876, 876, 711, 711, 800, 915, 610, 890, 890, 812, 825, 876, 610, 876, 900, 1000, 890};
		List<Integer> orders1 = Arrays.asList(l1);
		List<Integer> orders2 = Arrays.asList(l2);
		List<Integer> orders3 = Arrays.asList(l3);
		List<Integer> ordersReal = new ArrayList<Integer>();
		ordersReal.addAll(orders1);
		ordersReal.addAll(orders2);
		ordersReal.addAll(orders3);
		demo.getPruductionPlan(ordersReal, target);
		
		/*
		int testCount = 100;// 测试案例总数 
		int maxOrdersCount = 200;// 最大订单数
		int i = 0;
		do {
			// 构造测试案例：需要生成的总订单数量
			long ordersCount = 0;
			while (ordersCount == 0) {
				ordersCount = Math.round(Math.random() * maxOrdersCount);
			}

			// 构造测试案例：生成随机订单
			List<Integer> initialOrders = new ArrayList<Integer>();
			while (initialOrders.size() < ordersCount) {
				long oneOrder = Math.round(Math.random() * target);
				if (oneOrder > 0) {
					initialOrders.add((int)oneOrder);
				}
				Collections.sort(initialOrders);
				Collections.reverse(initialOrders);
			}
			
			// 制定生产切割方案
			demo.getPruductionPlan(initialOrders, target);
			
			i++;
		} while(i < testCount) ;
		*/
	}
	
	/**
	 * 计算生产切割方案
	 * @param initialOrders
	 * @param target
	 */
	public void getPruductionPlan(List<Integer> initialOrders, int target) {
		DecimalFormat format = new DecimalFormat("#.00");
		
		// 订单需由大到小排序
		Collections.sort(initialOrders);
		Collections.reverse(initialOrders);
		
		System.out.println(initialOrders.size() + "张订单" + initialOrders + "的切割方案为：");
		while (initialOrders.size() > 0) {
			List<Integer> resultOrders = new ArrayList<Integer>();
			this.selectOrdersToOneYUANLIAO(resultOrders, initialOrders, target);
			double sum = 0;
			System.out.print("凑一张原料：");
			for (Integer i : resultOrders) {
				sum += i;
				System.out.print(i);
				System.out.print("、");
			}
			double rate = sum/target;// 利用率
			System.out.print("\t剩余原料：" + (target - sum) + "，\t利用率：" + format.format(rate*100) + "%");
			if (rate <= 0.8) {
				System.out.println("\t◆◆◆");
			} else {
				System.out.println();
			}
		}
		System.out.println();
	}
	
	/**
	 * 凑一张原料
	 * @param resultOrders
	 * @param initialOrders
	 * @param target
	 */
	public void selectOrdersToOneYUANLIAO(List<Integer> resultOrders, List<Integer> initialOrders, int target) {
		if (target <= 0) {
			return ;
		}
		for (int i = 0; i < initialOrders.size(); i++) {
			int oneOrder = initialOrders.get(i);
			if (oneOrder <= target) {
				initialOrders.remove(i);
				resultOrders.add(oneOrder);
				if (i >= initialOrders.size()) {
					return ;
				}
				List<Integer> remainingOrders = initialOrders.subList(i, initialOrders.size());
				this.selectOrdersToOneYUANLIAO(resultOrders, remainingOrders, target - oneOrder);
				return ;
			}
		}
	}

}
